﻿using System.Linq;
using System.Text;
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

using System.Threading;
using System.Runtime.CompilerServices;

namespace TheGame
{
    public class Character
    {
        Animation currentAnimation;
        Animation prevAnimation;
        int direction;
        public Game1 game;
        public float AnimateRate = 1000 / 30;
        public int passesDone = 0;
        public bool canmove;
        public Rectangle DrawingRec;
        public Rectangle boundingBox;
        public Level CurrentLevel;
        public Color color;
        public MudokonAI AI;
        public ObjectA CURRENTOBJECTA;

        public bool DEAD = false;

        public int POSITION;
        

        public void UpdateBBox(Animation anim)
        {
            if (anim.FrameColl == anim.CurrentFrame)
            {
                boundingBox.X += 43 * anim.HopsX * Direction;
                boundingBox.Y -= 90 * anim.HopsY;
            }
        }
        public void Animate(Animation anim, int fromFrame, int toFrame)
        {
            CurrentAnimation = anim;
            UpdateBBox(anim);

            if (anim.CurrentFrame == 0)
            {
                if (direction == 1)
                {
                    anim.SpriteWidth = anim.SpriteRWidth;
                    anim.SpriteHeight = anim.SpriteRHeight;
                    anim.Sheet = anim.SheetR;
                }
                else
                {
                    anim.SpriteWidth = anim.SpriteLWidth;
                    anim.SpriteHeight = anim.SpriteLHeight;
                    anim.Sheet = anim.SheetL;
                }
                anim.Time = 0f;
                DrawingRec.Width = anim.SpriteWidth;
                DrawingRec.Height = anim.SpriteHeight;
                this.game.spriteCurrent = anim.Sheet;

                if (fromFrame == toFrame)
                    anim.LastFrameDone = true;
                else
                    anim.LastFrameDone = false;
                if (fromFrame < toFrame)
                {
                    anim.SourceRect = new Rectangle(fromFrame * anim.SpriteWidth, 0, anim.SpriteWidth, anim.SpriteHeight);
                    this.game.sourceRect = anim.SourceRect;
                    anim.Forward();
                }
            }
            if (anim.Time > anim.AnimateRate)
            {
                anim.Time = 0f;
                DrawingRec.Width = anim.SpriteWidth;
                DrawingRec.Height = anim.SpriteHeight;
                this.game.spriteCurrent = anim.Sheet;

                if (anim.Effect != null && anim.CurrentFrame == anim.Effect.FrameToPlay)
                    anim.Effect.Play();

                if (fromFrame == toFrame)
                    anim.LastFrameDone = true;
                else
                    anim.LastFrameDone = false;
                if (fromFrame < toFrame)
                {
                    anim.SourceRect = new Rectangle(fromFrame * anim.SpriteWidth, 0, anim.SpriteWidth, anim.SpriteHeight);
                    this.game.sourceRect = anim.SourceRect;
                    anim.Forward();
                }
            }
        }

        public void Animate(Animation anim, bool loop)
        {
            UpdateBBox(anim);
            CurrentAnimation = anim;

            if (anim.CurrentFrame == 0)
            {
                if (direction == 1)
                {
                    anim.SpriteWidth = anim.SpriteRWidth;
                    anim.SpriteHeight = anim.SpriteRHeight;
                    anim.Sheet = anim.SheetR;
                }
                else
                {
                    anim.SpriteWidth = anim.SpriteLWidth;
                    anim.SpriteHeight = anim.SpriteLHeight;
                    anim.Sheet = anim.SheetL;
                }
                DrawingRec.Width = anim.SpriteWidth;
                DrawingRec.Height = anim.SpriteHeight;

                this.game.spriteCurrent = anim.Sheet;
                currentAnimation = anim;
                if (anim.CurrentFrame < anim.FrameCount)
                {
                    anim.SourceRect = new Rectangle(anim.CurrentFrame * anim.SpriteWidth, 0, anim.SpriteWidth, anim.SpriteHeight);
                    this.game.sourceRect = anim.SourceRect;
                    anim.Forward();
                }

                if (loop)
                {
                    if (anim.CurrentFrame == anim.FrameCount)
                        anim.Reset();
                }

            }
            if (anim.Time > anim.AnimateRate)
            {
                

                anim.Time = 0f;

                DrawingRec.Width = anim.SpriteWidth;
                DrawingRec.Height = anim.SpriteHeight;
                this.game.spriteCurrent = anim.Sheet;

                if (anim.Effect != null && anim.CurrentFrame == anim.Effect.FrameToPlay)
                    anim.Effect.Play();

                if (anim.CurrentFrame == anim.FrameCount)
                    anim.LastFrameDone = true;
                else
                    anim.LastFrameDone = false;

                if (anim.CurrentFrame < anim.FrameCount)
                {
                    anim.SourceRect = new Rectangle(anim.CurrentFrame * anim.SpriteWidth, 0, anim.SpriteWidth, anim.SpriteHeight);
                    this.game.sourceRect = anim.SourceRect;
                    anim.Forward();
                }
                if (anim.LastFrameDone)
                {
                    if (anim.Name == "TURN")
                    {
                        direction = direction * -1;
                    }
                    
                }
                if (loop)
                {
                    if (anim.CurrentFrame == anim.FrameCount)
                        anim.Reset();
                }
            }
        }

        public Animation CurrentAnimation
        {
            get
            {
                return currentAnimation;
            }
            set
            {
                currentAnimation = value;
            }
        }

        public Animation PrevAnimation
        {
            get
            {
                return prevAnimation;
            }
            set
            {
                prevAnimation = value;
            }
        }
        

        public int Direction
        {
            get { return direction; }
            set { direction = value; }
        }
    }







    public class Animation
    {
        public int xSTART = 0;
        public int xEND = 0;
        public int ySTART = 0;
        public int yEND = 0;
        string name;
        int passes;
        int hopsX;
        int hopsY;
        Texture2D sheet;
        Texture2D sheetR;
        Texture2D sheetL;
        float animateRate;
        int spriteWidth;
        int spriteHeight;
        int spriteRWidth;
        int spriteRHeight;
        int spriteLWidth;
        int spriteLHeight;
        int frameCount;
        int currentFrame = 0;
        Rectangle sourceRect;
        bool lastFrameDone = false;
        float time;
        Animation next;
        Sound effect;
        int frameColl;

        bool toDO = false;

        public Animation()
        { }

        public Animation(Texture2D sheetR, Texture2D sheetL, float animateRate, int frameCount, string name, Animation next, Sound effect, int hopsX, int hopsY, int frameColl)
        {
            this.sheetR = sheetR;
            this.spriteRWidth = sheetR.Width / frameCount;
            this.spriteRHeight = sheetR.Height;

            this.sheetL = sheetL;
            this.spriteLWidth = sheetL.Width / frameCount;
            this.spriteLHeight = sheetL.Height;

            this.sheet = sheetR;
            this.spriteWidth = spriteRWidth;
            this.spriteHeight = spriteRHeight;

            this.frameCount = frameCount;
            this.animateRate = animateRate;
            this.effect = effect;
            this.name = name;
            this.hopsX = hopsX;
            this.hopsY = hopsY;
            this.frameColl = frameColl;

            this.time = 0f;
            sourceRect = new Rectangle(0, 0, spriteWidth, spriteHeight);
            this.next = next;

            if (name == "STOP_1" || name == "PASS_1")
                passes = 1;
            if (name == "STOP_2" || name == "PASS_2")
                passes = 2;
            if (name == "STOP_3" || name == "PASS_3")
                passes = 3;
        }

        public Animation(Texture2D sheetR, Texture2D sheetL, float animateRate, int frameCount, string name, int hopsX, int hopsY, int frameColl)
        {
            this.sheetR = sheetR;
            this.spriteRWidth = sheetR.Width / frameCount;
            this.spriteRHeight = sheetR.Height;

            this.sheetL = sheetL;
            this.spriteLWidth = sheetL.Width / frameCount;
            this.spriteLHeight = sheetL.Height;

            this.sheet = sheetR;
            this.spriteWidth = spriteRWidth;
            this.spriteHeight = spriteRHeight;
            this.frameCount = frameCount;
            this.animateRate = animateRate;
            this.name = name;
            this.hopsX = hopsX;
            this.hopsY = hopsY;
            this.frameColl = frameColl;

            this.time = 0f;
            sourceRect = new Rectangle(0, 0, spriteWidth, spriteHeight);

            if (name == "STOP_1" || name == "PASS_1")
                passes = 1;
            if (name == "STOP_2" || name == "PASS_2")
                passes = 2;
            if (name == "STOP_3" || name == "PASS_3")
                passes = 3;
        }

        public Animation(Texture2D sheetR, Texture2D sheetL, float animateRate, int frameCount, Sound effect, string name, int hopsX, int hopsY, int frameColl)
        {
            this.sheetR = sheetR;
            this.spriteRWidth = sheetR.Width / frameCount;
            this.spriteRHeight = sheetR.Height;

            this.sheetL = sheetL;
            this.spriteLWidth = sheetL.Width / frameCount;
            this.spriteLHeight = sheetL.Height;

            this.sheet = sheetR;
            this.spriteWidth = spriteRWidth;
            this.spriteHeight = spriteRHeight;

            this.frameCount = frameCount;
            this.animateRate = animateRate;
            this.name = name;
            this.effect = effect;
            this.hopsX = hopsX;
            this.hopsY = hopsY;
            this.frameColl = frameColl;
            //this.Abe.DrawingRec = Abe.DrawingRec;

            this.time = 0f;
            sourceRect = new Rectangle(0, 0, spriteWidth, spriteHeight);

            if (name == "STOP_1" || name == "PASS_1")
                passes = 1;
            if (name == "STOP_2" || name == "PASS_2")
                passes = 2;
            if (name == "STOP_3" || name == "PASS_3")
                passes = 3;
        }

        public Animation(Texture2D sheetR, Texture2D sheetL, float animateRate, int frameCount, string name, int hopsX, int hopsY, int frameColl, int xSTART, int xEND)
        {
            if (sheetR != null)
            {
                this.xSTART = xSTART;
                this.xEND = xEND;

                this.sheetR = sheetR;
                this.spriteRWidth = sheetR.Width / frameCount;
                this.spriteRHeight = sheetR.Height;

                this.sheetL = sheetL;
                this.spriteLWidth = sheetL.Width / frameCount;
                this.spriteLHeight = sheetL.Height;

                this.sheet = sheetR;
                this.spriteWidth = spriteRWidth;
                this.spriteHeight = spriteRHeight;
                this.frameCount = frameCount;
                this.animateRate = animateRate;
                this.name = name;
                this.hopsX = hopsX;
                this.hopsY = hopsY;
                this.frameColl = frameColl;
                //this.Abe.DrawingRec = Abe.DrawingRec;

                this.time = 0f;
                sourceRect = new Rectangle(0, 0, spriteWidth, spriteHeight);
            }

        }

        

        public Animation(Texture2D sheetR, Texture2D sheetL, float animateRate, int frameCount, string name, int hopsX, int hopsY, int frameColl, int xSTART, int xEND, int ySTART, int yEND)
        {
            this.xSTART = xSTART;
            this.xEND = xEND;
            this.ySTART = ySTART;
            this.yEND = yEND;

            this.sheetR = sheetR;
            this.spriteRWidth = sheetR.Width / frameCount;
            this.spriteRHeight = sheetR.Height;

            this.sheetL = sheetL;
            this.spriteLWidth = sheetL.Width / frameCount;
            this.spriteLHeight = sheetL.Height;

            this.sheet = sheetR;
            this.spriteWidth = spriteRWidth;
            this.spriteHeight = spriteRHeight;
            this.frameCount = frameCount;
            this.animateRate = animateRate;
            this.name = name;
            this.hopsX = hopsX;
            this.hopsY = hopsY;
            this.frameColl = frameColl;
            //this.Abe.DrawingRec = Abe.DrawingRec;

            this.time = 0f;
            sourceRect = new Rectangle(0, 0, spriteWidth, spriteHeight);

            if (name == "STOP_1" || name == "PASS_1")
                passes = 1;
            if (name == "STOP_2" || name == "PASS_2")
                passes = 2;
            if (name == "STOP_3" || name == "PASS_3")
                passes = 3;
        }
        public Animation(Texture2D sheetR, Texture2D sheetL, float animateRate, int frameCount, string name,Sound effect, int hopsX, int hopsY, int frameColl, int xSTART, int xEND)
        {
            this.xSTART = xSTART;
            this.xEND = xEND;

            this.sheetR = sheetR;
            this.spriteRWidth = sheetR.Width / frameCount;
            this.spriteRHeight = sheetR.Height;

            this.sheetL = sheetL;
            this.spriteLWidth = sheetL.Width / frameCount;
            this.spriteLHeight = sheetL.Height;

            this.sheet = sheetR;
            this.spriteWidth = spriteRWidth;
            this.spriteHeight = spriteRHeight;
            this.frameCount = frameCount;
            this.animateRate = animateRate;
            this.name = name;
            this.hopsX = hopsX;
            this.hopsY = hopsY;
            this.frameColl = frameColl;
            this.effect = effect;

            this.time = 0f;
            sourceRect = new Rectangle(0, 0, spriteWidth, spriteHeight);

            if (name == "STOP_1" || name == "PASS_1")
                passes = 1;
            if (name == "STOP_2" || name == "PASS_2")
                passes = 2;
            if (name == "STOP_3" || name == "PASS_3")
                passes = 3;
        }
        public Animation(Texture2D sheetR, Texture2D sheetL, float animateRate, int frameCount, string name, Sound effect, int hopsX, int hopsY, int frameColl, int xSTART, int xEND, int ySTART, int yEND)
        {
            this.xSTART = xSTART;
            this.xEND = xEND;
            this.ySTART = ySTART;
            this.yEND = yEND;

            this.sheetR = sheetR;
            this.spriteRWidth = sheetR.Width / frameCount;
            this.spriteRHeight = sheetR.Height;

            this.sheetL = sheetL;
            this.spriteLWidth = sheetL.Width / frameCount;
            this.spriteLHeight = sheetL.Height;

            this.sheet = sheetR;
            this.spriteWidth = spriteRWidth;
            this.spriteHeight = spriteRHeight;
            this.frameCount = frameCount;
            this.animateRate = animateRate;
            this.name = name;
            this.hopsX = hopsX;
            this.hopsY = hopsY;
            this.frameColl = frameColl;
            this.effect = effect;

            this.time = 0f;
            sourceRect = new Rectangle(0, 0, spriteWidth, spriteHeight);

            if (name == "STOP_1" || name == "PASS_1")
                passes = 1;
            if (name == "STOP_2" || name == "PASS_2")
                passes = 2;
            if (name == "STOP_3" || name == "PASS_3")
                passes = 3;
        }

        public Animation(Texture2D sheet, int frameCount)//OBJECT
        {
            this.time = 0f;
            this.frameCount = frameCount;
            this.animateRate = 1000 / 30;
            if (sheet != null)
            {
                this.sheet = sheet;
                this.spriteWidth = sheet.Width / frameCount;
                this.spriteHeight = sheet.Height;             
                
                sourceRect = new Rectangle(0, 0, spriteWidth, spriteHeight);
            }
        }

        public Animation(Texture2D sheet, Sound effect, int frameCount)//OBJECT+SOUND
        {
            this.time = 0f;
            this.effect = effect;
            this.frameCount = frameCount;
            this.animateRate = 1000 / 30;
            if (sheet != null)
            {
                this.sheet = sheet;
                this.spriteWidth = sheet.Width / frameCount;
                this.spriteHeight = sheet.Height;
                sourceRect = new Rectangle(0, 0, spriteWidth, spriteHeight);
            }
        }

        public void Reset()
        {
            currentFrame = 0;
            LastFrameDone = false;
            SourceRect = new Rectangle(CurrentFrame * SpriteWidth, 0, SpriteWidth, SpriteHeight);
        }

        public void Forward()
        {
            currentFrame++;
        }

        public bool isLastFrame()
        {
            if (CurrentFrame == FrameCount)
                return true;
            else
                return false;
        }

        public Sound Effect
        {
            get { return effect; }
        }

        public bool TODO
        {
            get
            {
                return toDO;
            }
            set
            {
                toDO = value;
            }
        }

        public Animation NEXT
        {
            get
            {
                return next;
            }
            set
            {
                next = value;
            }
        }

        public int FrameColl
        {
            get { return frameColl; }
        }

        public bool LastFrameDone
        {
            get
            {
                return lastFrameDone;
            }
            set
            {
                lastFrameDone = value;
            }
        }

        public float AnimateRate
        {
            get
            {
                return animateRate;
            }
            set
            {
                animateRate = value;
            }
        }

        public float Time
        {
            get
            {
                return time;
            }
            set
            {
                time = value;
            }
        }

        public int FrameCount
        {
            get
            {
                return frameCount;
            }
        }


        public Texture2D Sheet
        {
            get { return sheet; }
            set
            {
                sheet = value;
            }
        }

        public Texture2D SheetR
        {
            get
            {
                return sheetR;
            }
        }

        public Texture2D SheetL
        {
            get
            {
                return sheetL;
            }
        }

        public int CurrentFrame
        {
            get
            {
                return currentFrame;
            }
            set
            {
                currentFrame = value;
            }
        }

        public Rectangle SourceRect
        {
            get
            {
                return sourceRect;
            }
            set
            {
                sourceRect = value;
            }
        }

        public int SpriteWidth
        {
            get { return spriteWidth; }
            set
            {
                spriteWidth = value;
            }
        }

        public int SpriteHeight
        {
            get { return spriteHeight; }
            set
            {
                spriteHeight = value;
            }
        }

        public int SpriteRWidth
        {
            get
            {
                return spriteRWidth;
            }
        }

        public int SpriteRHeight
        {
            get
            {
                return spriteRHeight;
            }
        }
        public int SpriteLWidth
        {
            get
            {
                return spriteLWidth;
            }
        }

        public int SpriteLHeight
        {
            get
            {
                return spriteLHeight;
            }
        }

        public int Passes
        {
            get
            {
                return passes;
            }
            set { passes = value; }
        }

        public string Name
        {
            get
            {
                return name;
            }
        }

        public int HopsX
        {
            get { return hopsX; }
        }

        public int HopsY
        {
            get { return hopsY; }
        }


    }

}
